package platform

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/errors"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay"
	hlmodels "gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay/services"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/auth"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"

	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// HlPayController HlPay控制器
type HlPayController struct {
	client *hlPay.HlPayClient
	db     *gorm.DB
}

// NewHlPayController 创建HlPay控制器
func NewHlPayController(client *hlPay.HlPayClient) *HlPayController {
	return &HlPayController{
		client: client,
		db:     database.DB,
	}
}

// ==================== 卡片管理相关接口 ====================

// GetCardBin 获取卡Bin信息
func (c *HlPayController) GetCardBin(ctx *gin.Context) {
	result, err := services.GetCardBin(ctx.Request.Context(), c.client)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_card_bin_failed", err)
		return
	}

	common.Success(ctx, result)
}

// GetStateList 获取州列表
func (c *HlPayController) GetStateList(ctx *gin.Context) {
	result, err := services.GetStateList(ctx.Request.Context(), c.client)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_state_list_failed", err)
		return
	}

	common.Success(ctx, result)
}

// GetCardList 获取卡片列表
func (c *HlPayController) GetCardList(ctx *gin.Context) {
	// 获取当前用户ID
	var userID int64
	if claims, exists := ctx.Get("claims"); exists {
		if authClaims, ok := claims.(*auth.Claims); ok {
			userID = authClaims.UserID
		}
	}

	if userID == 0 {
		common.Error(ctx, http.StatusUnauthorized, "user_not_found", fmt.Errorf("user ID not found"))
		return
	}

	// 获取分页参数
	page, pageSize := common.GetPaginationParams(ctx)

	// 绑定form参数
	var params hlmodels.CardListRequest
	if err := ctx.ShouldBind(&params); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_params", err)
		return
	}

	// 生成缓存键（包含用户ID，因为不同用户看到的数据不同）
	cacheKey := fmt.Sprintf("hlpay:card_list:user_%d:%s:%s:%s",
		userID,
		func() string {
			if params.CardNo != "" {
				return params.CardNo
			}
			return "all"
		}(),
		func() string {
			if params.Name != "" {
				return params.Name
			}
			return "all"
		}(),
		func() string {
			if params.Status != "" {
				return params.Status
			}
			return "all"
		}())

	// 首先尝试从Redis获取缓存
	cachedData, err := database.Get(ctx.Request.Context(), cacheKey)
	if err == nil && cachedData != "" {
		// 缓存命中，解析原始数据并重新进行权限过滤和信息合并
		log.Printf("Cache hit for key: %s", cacheKey)
		var allResult hlmodels.CardListResponse
		if err := json.Unmarshal([]byte(cachedData), &allResult); err == nil {
			// 获取用户的所有卡ID（每次缓存命中都需要重新查询，确保数据最新）
			var userCards []models.UserCard
			if err := c.db.Where("user_id = ? AND platform = ?", userID, "hlPay").Find(&userCards).Error; err != nil {
				log.Printf("Failed to get user cards from database: %v", err)
				common.Error(ctx, http.StatusInternalServerError, "get_user_cards_failed", err)
				return
			}

			// 创建用户卡ID的映射，用于快速查找，同时保存用户卡信息
			userCardIDMap := make(map[string]bool)
			userCardInfoMap := make(map[string]models.UserCard)
			for _, userCard := range userCards {
				userCardIDMap[userCard.CardID] = true
				userCardInfoMap[userCard.CardID] = userCard
			}

			// 过滤出用户有权限的卡，并合并用户数据库中的信息
			var authorizedRows []hlmodels.CardItem
			for _, card := range allResult.Rows {
				if userCardIDMap[card.ID] {
					// 获取用户数据库中的卡信息
					userCard := userCardInfoMap[card.ID]

					// 合并用户数据库中的信息
					card.Nickname = userCard.NikeName
					card.TotalTransferAmount = userCard.TotalTransferAmount.String()

					authorizedRows = append(authorizedRows, card)
				}
			}

			// 从过滤后的数据中截取对应的分页数据
			startIndex := int((page - 1) * pageSize)
			endIndex := startIndex + int(pageSize)

			if startIndex >= len(authorizedRows) {
				// 请求的页码超出范围，返回空结果
				result := hlmodels.CardListResponse{
					Total:   int(len(authorizedRows)),
					Rows:    []hlmodels.CardItem{},
					Code:    allResult.Code,
					Message: allResult.Message,
				}
				common.Success(ctx, result)
				return
			}

			if endIndex > len(authorizedRows) {
				endIndex = len(authorizedRows)
			}

			result := hlmodels.CardListResponse{
				Total:   int(len(authorizedRows)),
				Rows:    authorizedRows[startIndex:endIndex],
				Code:    allResult.Code,
				Message: allResult.Message,
			}
			common.Success(ctx, result)
			return
		} else {
			log.Printf("Failed to unmarshal cached data: %v", err)
		}
	} else {
		log.Printf("Cache miss for key: %s, error: %v", cacheKey, err)
	}

	// 缓存未命中，获取所有数据
	log.Printf("Fetching all card data with pageSize=1000 for user %d...", userID)

	// 先获取第一页，pageSize=1000
	firstPageResult, err := services.GetCardList(ctx.Request.Context(), c.client, 1, 1000, &params)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_card_list_failed", err)
		return
	}

	if firstPageResult == nil {
		common.Error(ctx, http.StatusInternalServerError, "get_card_list_failed", fmt.Errorf("first page result is nil"))
		return
	}

	// 合并所有数据
	allRows := firstPageResult.Rows
	total := firstPageResult.Total

	// 计算还需要获取多少页
	totalPages := (total + 999) / 1000 // 向上取整

	log.Printf("Total cards from API: %d, Total pages: %d", total, totalPages)

	// 获取剩余页的数据
	for currentPage := 2; currentPage <= totalPages; currentPage++ {
		log.Printf("Fetching page %d/%d...", currentPage, totalPages)

		pageResult, err := services.GetCardList(ctx.Request.Context(), c.client, currentPage, 1000, &params)
		if err != nil {
			log.Printf("Failed to fetch page %d: %v", currentPage, err)
			continue
		}

		if pageResult != nil && len(pageResult.Rows) > 0 {
			allRows = append(allRows, pageResult.Rows...)
		}
	}

	log.Printf("Total cards fetched from API: %d", len(allRows))

	// 获取用户的所有卡ID
	var userCards []models.UserCard
	if err := c.db.Where("user_id = ? AND platform = ?", userID, "hlPay").Find(&userCards).Error; err != nil {
		log.Printf("Failed to get user cards from database: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "get_user_cards_failed", err)
		return
	}

	// 创建用户卡ID的映射，用于快速查找，同时保存用户卡信息
	userCardIDMap := make(map[string]bool)
	userCardInfoMap := make(map[string]models.UserCard)
	for _, userCard := range userCards {
		userCardIDMap[userCard.CardID] = true
		userCardInfoMap[userCard.CardID] = userCard
	}

	log.Printf("User %d has %d cards in database", userID, len(userCards))

	// 过滤出用户有权限的卡，并合并用户数据库中的信息
	var authorizedRows []hlmodels.CardItem
	for _, card := range allRows {
		if userCardIDMap[card.ID] {
			// 获取用户数据库中的卡信息
			userCard := userCardInfoMap[card.ID]

			// 合并用户数据库中的信息
			card.Nickname = userCard.NikeName
			card.TotalTransferAmount = userCard.TotalTransferAmount.String()

			authorizedRows = append(authorizedRows, card)
		}
	}

	log.Printf("User %d has access to %d cards out of %d total cards", userID, len(authorizedRows), len(allRows))

	// 构建完整的结果（存储原始数据，不包含用户权限过滤）
	allResult := hlmodels.CardListResponse{
		Total:   total,   // 使用原始的总数
		Rows:    allRows, // 使用原始的所有数据
		Code:    firstPageResult.Code,
		Message: firstPageResult.Message,
	}

	// 将原始结果缓存到Redis，过期时间60秒
	if resultBytes, err := json.Marshal(allResult); err == nil {
		if err := database.SetWithExpiration(ctx.Request.Context(), cacheKey, string(resultBytes), 60*time.Second); err != nil {
			log.Printf("Failed to cache original card list data: %v", err)
		} else {
			log.Printf("Successfully cached original card list data for key: %s, total cards: %d", cacheKey, len(allRows))
		}
	} else {
		log.Printf("Failed to marshal original result for caching: %v", err)
	}

	// 返回请求的分页数据
	startIndex := int((page - 1) * pageSize)
	endIndex := startIndex + int(pageSize)

	if startIndex >= len(authorizedRows) {
		// 请求的页码超出范围，返回空结果
		result := hlmodels.CardListResponse{
			Total:   int(len(authorizedRows)),
			Rows:    []hlmodels.CardItem{},
			Code:    firstPageResult.Code,
			Message: firstPageResult.Message,
		}
		common.Success(ctx, result)
		return
	}

	if endIndex > len(authorizedRows) {
		endIndex = len(authorizedRows)
	}

	result := hlmodels.CardListResponse{
		Total:   int(len(authorizedRows)),
		Rows:    authorizedRows[startIndex:endIndex],
		Code:    firstPageResult.Code,
		Message: firstPageResult.Message,
	}

	common.Success(ctx, result)
}

// GetCardDetail 获取卡片详情
func (c *HlPayController) GetCardDetail(ctx *gin.Context) {
	// Get card ID from URL parameter
	cardID := ctx.Param("id")
	if cardID == "" {
		common.Error(ctx, http.StatusBadRequest, "card_id_is_required", nil)
		return
	}

	result, err := services.GetCardDetail(ctx.Request.Context(), c.client, cardID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_card_detail_failed", err)
		return
	}

	common.Success(ctx, result)
}

// GetVerificationCode 获取卡片验证码
func (c *HlPayController) GetVerificationCode(ctx *gin.Context) {
	cardID := ctx.Param("id")
	if cardID == "" {
		common.Error(ctx, http.StatusBadRequest, "card_id_is_required", nil)
		return
	}

	result, err := services.GetVerificationCode(ctx.Request.Context(), c.client, cardID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_verification_code_failed", err)
		return
	}

	common.Success(ctx, result)
}

// OpenCard 开卡
func (c *HlPayController) OpenCard(ctx *gin.Context) {
	var params hlmodels.OpenCardRequest
	if err := ctx.ShouldBindJSON(&params); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_body", err)
		return
	}

	result, err := services.OpenCard(ctx.Request.Context(), c.client, &params)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "open_card_failed", err)
		return
	}

	// 获取当前用户ID
	var userID string
	if claims, exists := ctx.Get("claims"); exists {
		if authClaims, ok := claims.(*auth.Claims); ok {
			userID = fmt.Sprintf("%d", authClaims.UserID)
		}
	}

	// 开卡成功后，输出调试信息
	log.Println("=== 开卡成功调试信息 ===")

	// 输出前端参数
	frontendParams, _ := json.MarshalIndent(params, "", "  ")
	log.Printf("前端参数: %s", string(frontendParams))

	// 输出第三方请求返回结果
	thirdPartyResult, _ := json.MarshalIndent(result, "", "  ")
	log.Printf("第三方请求返回: %s", string(thirdPartyResult))

	// 输出当前用户ID
	log.Printf("当前用户ID: %s", userID)
	log.Println("=== 调试信息结束 ===")

	// 保存卡片信息到本地数据库
	if result.Data != "" {
		// 转换用户ID为int64
		userIDInt, err := strconv.ParseInt(userID, 10, 64)
		if err != nil {
			log.Printf("Failed to parse user ID: %v", err)
		} else {
			// 创建用户卡记录
			userCard := &models.UserCard{
				UserID:              userIDInt,
				CardID:              result.Data,
				Platform:            "hlPay",
				CardStatus:          "active",
				CardBin:             params.Bin,
				NikeName:            "",
				TotalTransferAmount: decimal.NewFromFloat(params.Cost),
				CardType:            "recharge",
			}

			// 如果有nickname，设置昵称
			if params.Nickname != nil && *params.Nickname != "" {
				userCard.NikeName = *params.Nickname
			}

			// 保存到数据库
			if err := c.db.Create(userCard).Error; err != nil {
				log.Printf("Failed to save card to database: %v", err)
			} else {
				log.Printf("Successfully saved card to database: CardID=%s, UserID=%d, Nickname=%s",
					result.Data, userIDInt, userCard.NikeName)
			}
		}
	}

	common.Success(ctx, result)
}

// UpdateCard 更新卡片
// func (c *HlPayController) UpdateCard(ctx *gin.Context) {
// 	// TODO: 实现更新卡片逻辑
// 	common.Success(ctx, gin.H{
// 		"message": "UpdateCard - 功能待实现",
// 	})
// }

// FreezeCard 冻结卡片
func (c *HlPayController) FreezeCard(ctx *gin.Context) {
	cardID := ctx.Param("id")
	if cardID == "" {
		common.Error(ctx, http.StatusBadRequest, "card_id_is_required", nil)
		return
	}

	result, err := services.FreezeCard(ctx.Request.Context(), c.client, cardID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "freeze_card_failed", err)
		return
	}

	common.Success(ctx, result)
}

// EnableCard 解冻卡片
func (c *HlPayController) EnableCard(ctx *gin.Context) {
	cardID := ctx.Param("id")
	if cardID == "" {
		common.Error(ctx, http.StatusBadRequest, "card_id_is_required", nil)
		return
	}

	result, err := services.EnableCard(ctx.Request.Context(), c.client, cardID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "enable_card_failed", err)
		return
	}

	common.Success(ctx, result)
}

// CancelCard 注销卡片
func (c *HlPayController) CancelCard(ctx *gin.Context) {
	cardID := ctx.Param("id")
	if cardID == "" {
		common.Error(ctx, http.StatusBadRequest, "card_id_is_required", nil)
		return
	}

	result, err := services.CancelCard(ctx.Request.Context(), c.client, cardID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "cancel_card_failed", err)
		return
	}

	common.Success(ctx, result)
}

// Recharge 充值
func (c *HlPayController) Recharge(ctx *gin.Context) {
	var params hlmodels.RechargeRequest
	if err := ctx.ShouldBindJSON(&params); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_body", err)
		return
	}

	result, err := services.Recharge(ctx.Request.Context(), c.client, &params)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "recharge_failed", err)
		return
	}

	// 充值成功后，更新本地数据库中卡片的TotalTransferAmount
	// 获取当前用户信息
	claims, exists := ctx.Get("claims")
	if exists {
		if authClaims, ok := claims.(*auth.Claims); ok {
			userID := authClaims.UserID

			// 更新卡片的TotalTransferAmount
			var userCard models.UserCard
			if err := c.db.Where("card_id = ? AND user_id = ?", params.ID, userID).First(&userCard).Error; err == nil {
				// 累加充值金额到现有的TotalTransferAmount
				newTotalTransferAmount := userCard.TotalTransferAmount.Add(decimal.NewFromFloat(params.Amount))
				if err := c.db.Model(&userCard).Update("TotalTransferAmount", newTotalTransferAmount).Error; err != nil {
					log.Printf("[HlPay Recharge] 更新卡片TotalTransferAmount失败: %v", err)
				} else {
					log.Printf("[HlPay Recharge] 更新卡片TotalTransferAmount成功: CardID=%s, 新增充值金额=%f, 总金额=%s",
						params.ID, params.Amount, newTotalTransferAmount.String())
				}
			} else {
				log.Printf("[HlPay Recharge] 找不到卡片记录: CardID=%s, UserID=%d", params.ID, userID)
			}
		}
	}

	common.Success(ctx, result)
}

// Withdraw 提现
func (c *HlPayController) Withdraw(ctx *gin.Context) {
	var params hlmodels.WithdrawRequest
	if err := ctx.ShouldBindJSON(&params); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_body", err)
		return
	}

	result, err := services.Withdraw(ctx.Request.Context(), c.client, &params)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "withdraw_failed", err)
		return
	}

	common.Success(ctx, result)
}

// RechargeReturn 卡金额退还
func (c *HlPayController) RechargeReturn(ctx *gin.Context) {
	var req struct {
		CardId       string `json:"cardId" binding:"required"`
		ReturnAmount string `json:"returnAmount" binding:"required"`
		RequestId    string `json:"requestId" binding:"required"`
	}

	// 1. 参数验证
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_body", err)
		return
	}

	// 2. 获取当前用户信息
	claims, exists := ctx.Get("claims")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}
	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "invalid_token_claims", nil)
		return
	}
	userID := authClaims.UserID
	roleID := authClaims.RoleID

	// 3. 验证卡片是否存在且属于当前用户
	var userCard models.UserCard
	if err := c.db.Where("card_id = ? AND user_id = ?", req.CardId, userID).First(&userCard).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			common.Error(ctx, http.StatusNotFound, "card_not_found", fmt.Errorf("card not found or not owned by user"))
			return
		}
		common.Error(ctx, http.StatusInternalServerError, "database_error", err)
		return
	}

	// 添加调试信息
	log.Printf("[RechargeReturn] 卡片信息: CardID=%s, UserID=%d, TotalTransferAmount=%s, Platform=%s",
		userCard.CardID, userCard.UserID, userCard.TotalTransferAmount.String(), userCard.Platform)

	// 4. 解析退还金额
	returnAmount, err := decimal.NewFromString(req.ReturnAmount)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_return_amount", fmt.Errorf("invalid return amount format"))
		return
	}

	// 5. 验证退还金额是否超过总转账金额
	if returnAmount.GreaterThan(userCard.TotalTransferAmount) {
		common.Error(ctx, http.StatusBadRequest, "insufficient_funds", fmt.Errorf("refund amount %s exceeds total transfer amount %s",
			returnAmount.String(), userCard.TotalTransferAmount.String()))
		return
	}

	// 6. 开始数据库事务
	tx := c.db.Begin()
	if tx.Error != nil {
		common.Error(ctx, http.StatusInternalServerError, "transaction_start_failed", tx.Error)
		return
	}

	// 7. 更新卡片的总转账金额
	newTotalTransferAmount := userCard.TotalTransferAmount.Sub(returnAmount)
	if err := tx.Model(&models.UserCard{}).
		Where("card_id = ? AND user_id = ?", req.CardId, userID).
		Update("TotalTransferAmount", newTotalTransferAmount).Error; err != nil {
		tx.Rollback()
		common.Error(ctx, http.StatusInternalServerError, "update_card_amount_failed", err)
		return
	}

	// 8. 根据用户角色更新余额
	switch roleID {
	case 2: // 普通用户，不需要处理主子账户扣款
		// 直接跳过扣款逻辑
	case 3: // 主账号
		if err := tx.Model(&models.MasterAccount{}).
			Where("user_id = ?", userID).
			Update("balance", gorm.Expr("balance + ?", returnAmount)).Error; err != nil {
			tx.Rollback()
			common.Error(ctx, http.StatusInternalServerError, "update_master_account_balance_failed", err)
			return
		}
	case 5: // 子账号
		if err := tx.Model(&models.SubAccount{}).
			Where("user_id = ?", userID).
			Update("balance", gorm.Expr("balance + ?", returnAmount)).Error; err != nil {
			tx.Rollback()
			common.Error(ctx, http.StatusInternalServerError, "update_sub_account_balance_failed", err)
			return
		}
	default:
		tx.Rollback()
		common.Error(ctx, http.StatusBadRequest, "invalid_user_role", fmt.Errorf("invalid user role: %d", roleID))
		return
	}

	// 9. 调用HlPay的Withdraw API
	withdrawParams := &hlmodels.WithdrawRequest{
		ID:     req.CardId,
		Amount: returnAmount.InexactFloat64(),
		Remark: fmt.Sprintf("金额退还 - %s", req.RequestId),
	}

	_, err = services.Withdraw(ctx.Request.Context(), c.client, withdrawParams)
	if err != nil {
		// 即使远程API失败，本地数据库已经更新，记录错误但继续
		log.Printf("HlPay Withdraw API failed: %v", err)
	}

	// 10. 提交事务
	if err := tx.Commit().Error; err != nil {
		common.Error(ctx, http.StatusInternalServerError, "transaction_commit_failed", err)
		return
	}

	// 11. 构造响应
	response := gin.H{
		"code": "200",
		"msg": map[string]string{
			"CN": "金额退还成功",
			"EN": "Amount returned successfully",
			"VN": "Hoàn tiền thành công",
		},
		"data": map[string]interface{}{
			"cardId":       req.CardId,
			"returnAmount": returnAmount.String(),
			"requestId":    req.RequestId,
			"note":         "Local database updated successfully",
		},
	}

	// 如果远程API失败，添加错误信息
	if err != nil {
		response["code"] = "400"
		response["msg"] = map[string]string{
			"CN": "金额退还失败",
			"EN": "Failed to return amount",
			"VN": "Hoàn tiền thất bại",
		}
		response["note"] = "Local database updated successfully, but remote operation returned error"
	}

	common.Success(ctx, response)
}

// BatchOpenCards 批量开卡
func (c *HlPayController) BatchOpenCards(ctx *gin.Context) {
	// 获取用户角色和余额信息
	userInfo, err := c.getUserRoleAndBalance(ctx)
	if err != nil {
		common.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	var params hlmodels.BatchOpenCardRequest
	if err := ctx.ShouldBindJSON(&params); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_body", err)
		return
	}

	// 检查余额（批量开卡时，总充值金额 = 单张卡充值金额 × 批量数量）
	if params.Cost > 0 {
		// 解析批量数量
		batchCount := 1
		if params.BatchCount != "" {
			if count, err := strconv.Atoi(params.BatchCount); err == nil && count > 0 {
				batchCount = count
			}
		}

		totalRechargeAmount := params.Cost * float64(batchCount)

		// 根据用户角色检查相应的余额
		switch userInfo.RoleID {
		case 2: // 普通用户 - 检查hlpay_account_balances表余额
			// 对于普通用户，需要从请求中获取账户号
			// 这里需要根据实际情况获取账户号，可能需要从请求参数中获取
			log.Printf("[BatchOpenCards] 普通用户批量开卡，需要检查hlpay_account_balances表余额，总金额: %f", totalRechargeAmount)
			// TODO: 实现普通用户的余额检查逻辑

		case 3: // 主账号 - 检查主账号表余额
			if userInfo.Balance.LessThan(decimal.NewFromFloat(totalRechargeAmount)) {
				common.Error(ctx, http.StatusBadRequest, "insufficient_balance", fmt.Errorf("主账号余额不足: %s < %f", userInfo.Balance.String(), totalRechargeAmount))
				return
			}
			log.Printf("[BatchOpenCards] 主账号余额检查通过: %s >= %f", userInfo.Balance.String(), totalRechargeAmount)

		case 5: // 子账号 - 检查子账号表余额
			if userInfo.Balance.LessThan(decimal.NewFromFloat(totalRechargeAmount)) {
				common.Error(ctx, http.StatusBadRequest, "insufficient_balance", fmt.Errorf("子账号余额不足: %s < %f", userInfo.Balance.String(), totalRechargeAmount))
				return
			}
			log.Printf("[BatchOpenCards] 子账号余额检查通过: %s >= %f", userInfo.Balance.String(), totalRechargeAmount)

		default:
			common.Error(ctx, http.StatusBadRequest, "invalid_user_role", fmt.Errorf("不支持的用户角色: %d", userInfo.RoleID))
			return
		}
	}

	// 调用批量开卡服务
	result, err := services.BatchOpenCards(ctx.Request.Context(), c.client, &params)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "batch_open_card_failed", err)
		return
	}

	// 开卡成功后，扣除数据库中的余额
	if params.Cost > 0 && result.Code == 200 {
		// 解析批量数量
		batchCount := 1
		if params.BatchCount != "" {
			if count, err := strconv.Atoi(params.BatchCount); err == nil && count > 0 {
				batchCount = count
			}
		}

		totalRechargeAmount := params.Cost * float64(batchCount)
		rechargeAmountDecimal := decimal.NewFromFloat(totalRechargeAmount)

		// 使用统一的余额更新函数
		if err := c.updateBalanceForRole(ctx, userInfo.UserID, int(userInfo.RoleID), rechargeAmountDecimal, "deduct", "hlpay", ""); err != nil {
			log.Printf("[BatchOpenCards] HlPay余额扣除失败: %v", err)
			// 注意：这里不返回错误，因为开卡已经成功，余额扣除失败不应该影响开卡结果
			// 但应该记录日志以便后续处理
		} else {
			log.Printf("[BatchOpenCards] HlPay余额扣除成功: 总金额=%s (单张卡=%f × 批量数量=%d), 用户ID=%d",
				rechargeAmountDecimal.String(), params.Cost, batchCount, userInfo.UserID)
		}
	}

	common.Success(ctx, result)
}

// GetCardTask 查询开卡任务
func (c *HlPayController) GetCardTask(ctx *gin.Context) {
	// 从URL参数获取任务ID
	taskID := ctx.Param("taskId")
	if taskID == "" {
		common.Error(ctx, http.StatusBadRequest, "task_id_is_required", nil)
		return
	}

	result, err := services.GetCardTask(ctx.Request.Context(), c.client, taskID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_card_task_failed", err)
		return
	}

	common.Success(ctx, result)
}

// ==================== 账户管理相关接口 ====================

// GetAccountList 获取账户列表
// func (c *HlPayController) GetAccountList(ctx *gin.Context) {
// 	// TODO: 实现获取账户列表逻辑
// 	common.Success(ctx, gin.H{
// 		"message": "GetAccountList - 功能待实现",
// 	})
// }

// GetAccountBalance 获取账户余额
// func (c *HlPayController) GetAccountBalance(ctx *gin.Context) {
// 	// TODO: 实现获取账户余额逻辑
// 	common.Success(ctx, gin.H{
// 		"message": "GetAccountBalance - 功能待实现",
// 	})
// }

// GetAccountHistory 获取账户历史
// func (c *HlPayController) GetAccountHistory(ctx *gin.Context) {
// 	// TODO: 实现获取账户历史逻辑
// 	common.Success(ctx, gin.H{
// 		"message": "GetAccountHistory - 功能待实现",
// 	})
// }

// ==================== 交易管理相关接口 ====================

// GetTransactionList 获取交易列表
func (c *HlPayController) GetTransactionList(ctx *gin.Context) {
	var params hlmodels.CardTransactionDetailRequest
	if err := ctx.ShouldBind(&params); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_params", err)
		return
	}

	result, err := services.GetCardTransactionDetail(ctx.Request.Context(), c.client, &params)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_card_transaction_detail_failed", err)
		return
	}

	common.Success(ctx, result)
}

// GetTransactionDetail 获取交易详情
// func (c *HlPayController) GetTransactionDetail(ctx *gin.Context) {
// 	// TODO: 实现获取交易详情逻辑
// 	common.Success(ctx, gin.H{
// 		"message": "GetTransactionDetail - 功能待实现",
// 	})
// }

// getUserRoleAndBalance 获取用户角色和余额信息
func (c *HlPayController) getUserRoleAndBalance(ctx *gin.Context) (*UserRoleBalance, error) {
	claims, exists := ctx.Get("claims")
	if !exists {
		return nil, errors.NewAppError(http.StatusUnauthorized, "unauthorized", nil)
	}
	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		return nil, errors.NewAppError(http.StatusInternalServerError, "invalid_token_claims", nil)
	}

	userID := authClaims.UserID
	roleID := authClaims.RoleID
	var balance decimal.Decimal

	switch roleID {
	case 2: // 普通用户 - 返回0余额
		balance = decimal.Zero
	case 3: // 主账号
		var masterAccount models.MasterAccount
		if err := c.db.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			return nil, errors.NewAppError(http.StatusInternalServerError, "get_master_account_failed", err)
		}
		balance = masterAccount.Balance
	case 5: // 子账号
		var subAccount models.SubAccount
		if err := c.db.Where("user_id = ?", userID).First(&subAccount).Error; err != nil {
			return nil, errors.NewAppError(http.StatusInternalServerError, "get_sub_account_failed", err)
		}
		balance = subAccount.Balance
	}

	return &UserRoleBalance{
		RoleID:  roleID,
		UserID:  userID,
		Balance: balance,
	}, nil
}

// updateBalanceForRole 根据用户角色更新相应的余额
func (c *HlPayController) updateBalanceForRole(ctx *gin.Context, userID int64, roleID int, amount decimal.Decimal, operation string, platformType string, accountNo string) error {
	// 开始事务
	tx := c.db.Begin()
	if tx.Error != nil {
		return fmt.Errorf("开始事务失败: %v", tx.Error)
	}

	// 根据操作类型确定是增加还是减少余额
	var updateAmount decimal.Decimal
	switch operation {
	case "deduct", "decrease", "subtract":
		updateAmount = amount.Neg() // 负数表示扣除
	case "add", "increase", "recharge":
		updateAmount = amount // 正数表示增加
	default:
		tx.Rollback()
		return fmt.Errorf("不支持的操作类型: %s", operation)
	}

	// 根据用户角色更新相应的余额
	switch roleID {
	case 2: // 普通用户
		// 对于HlPay平台，需要更新hlpay_account_balances表
		if platformType == "hlpay" && accountNo != "" {
			var account models.HlPayAccountBalance
			if err := tx.Where("account_no = ?", accountNo).First(&account).Error; err != nil {
				tx.Rollback()
				return fmt.Errorf("找不到HlPay账户记录: %v", err)
			}

			// 检查余额是否足够（如果是扣除操作）
			if updateAmount.IsNegative() && account.RealTimeBalance.LessThan(amount) {
				tx.Rollback()
				return fmt.Errorf("HlPay账户余额不足: %s < %s", account.RealTimeBalance.String(), amount.String())
			}

			newBalance := account.RealTimeBalance.Add(updateAmount)
			if err := tx.Model(&account).Update("real_time_balance", newBalance).Error; err != nil {
				tx.Rollback()
				return fmt.Errorf("更新HlPay账户余额失败: %v", err)
			}

			log.Printf("[updateBalanceForRole] HlPay账户余额更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
				accountNo, operation, amount.String(), account.RealTimeBalance.String(), newBalance.String())
		} else {
			log.Printf("[updateBalanceForRole] 普通用户，非HlPay平台或账户号为空，跳过余额更新")
		}

	case 3: // 主账号
		// 更新主账号余额
		var masterAccount models.MasterAccount
		if err := tx.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("找不到主账号记录: %v", err)
		}

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && masterAccount.Balance.LessThan(amount) {
			tx.Rollback()
			return fmt.Errorf("主账号余额不足: %s < %s", masterAccount.Balance.String(), amount.String())
		}

		newBalance := masterAccount.Balance.Add(updateAmount)
		if err := tx.Model(&masterAccount).Update("balance", newBalance).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("更新主账号余额失败: %v", err)
		}

		// 如果主账号有对应的矩阵账户，同时更新HlPay账户余额
		if platformType == "hlpay" {
			var userMatrixAccount models.UserMatrixAccount
			if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err == nil {
				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ?", userMatrixAccount.MatrixAccount).First(&hlpayAccount).Error; err == nil {
					// 同步更新HlPay账户余额
					hlpayNewBalance := hlpayAccount.RealTimeBalance.Add(updateAmount)
					if err := tx.Model(&hlpayAccount).Update("real_time_balance", hlpayNewBalance).Error; err != nil {
						tx.Rollback()
						return fmt.Errorf("同步更新HlPay账户余额失败: %v", err)
					}

					log.Printf("[updateBalanceForRole] 主账号HlPay账户余额同步更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
						hlpayAccount.AccountNo, operation, amount.String(), hlpayAccount.RealTimeBalance.String(), hlpayNewBalance.String())
				}
			}
		}

		log.Printf("[updateBalanceForRole] 主账号余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), masterAccount.Balance.String(), newBalance.String())

	case 5: // 子账号
		// 更新子账号余额
		var subAccount models.SubAccount
		if err := tx.Where("user_id = ?", userID).First(&subAccount).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("找不到子账号记录: %v", err)
		}

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && subAccount.Balance.LessThan(amount) {
			tx.Rollback()
			return fmt.Errorf("子账号余额不足: %s < %s", subAccount.Balance.String(), amount.String())
		}

		newBalance := subAccount.Balance.Add(updateAmount)
		if err := tx.Model(&subAccount).Update("balance", newBalance).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("更新子账号余额失败: %v", err)
		}

		// 如果子账号有对应的矩阵账户，同时更新HlPay账户余额
		if platformType == "hlpay" {
			var userMatrixAccount models.UserMatrixAccount
			if err := tx.Where("user_id = ? AND platform_type = ?", userID, "hlpay").First(&userMatrixAccount).Error; err == nil {
				// 查找对应的HlPay账户余额记录
				var hlpayAccount models.HlPayAccountBalance
				if err := tx.Where("owner_no = ?", userMatrixAccount.MatrixAccount).First(&hlpayAccount).Error; err == nil {
					// 同步更新HlPay账户余额
					hlpayNewBalance := hlpayAccount.RealTimeBalance.Add(updateAmount)
					if err := tx.Model(&hlpayAccount).Update("real_time_balance", hlpayNewBalance).Error; err != nil {
						tx.Rollback()
						return fmt.Errorf("同步更新HlPay账户余额失败: %v", err)
					}

					log.Printf("[updateBalanceForRole] 子账号HlPay账户余额同步更新成功: 账户=%s, 操作=%s, 金额=%s, 余额变化: %s -> %s",
						hlpayAccount.AccountNo, operation, amount.String(), hlpayAccount.RealTimeBalance.String(), hlpayNewBalance.String())
				}
			}
		}

		log.Printf("[updateBalanceForRole] 子账号余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), subAccount.Balance.String(), newBalance.String())

	default:
		// 对于其他角色，尝试从主账号表更新余额（保持向后兼容）
		var masterAccount models.MasterAccount
		if err := tx.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("找不到主账号记录: %v", err)
		}

		// 检查余额是否足够（如果是扣除操作）
		if updateAmount.IsNegative() && masterAccount.Balance.LessThan(amount) {
			tx.Rollback()
			return fmt.Errorf("主账号余额不足: %s < %s", masterAccount.Balance.String(), amount.String())
		}

		newBalance := masterAccount.Balance.Add(updateAmount)
		if err := tx.Model(&masterAccount).Update("balance", newBalance).Error; err != nil {
			tx.Rollback()
			return fmt.Errorf("更新主账号余额失败: %v", err)
		}

		log.Printf("[updateBalanceForRole] 默认角色余额更新成功: 用户ID=%d, 操作=%s, 金额=%s, 余额变化: %s -> %s",
			userID, operation, amount.String(), masterAccount.Balance.String(), newBalance.String())
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		return fmt.Errorf("提交事务失败: %v", err)
	}

	return nil
}
